/*! \file Buffer.cpp
 *	\brief 
 *
 *	created:	2010/12/12
 *	created:	12:12:2010   19:15
 *	filename: 	C:\src\tactics-engine\libs\gd_dx11\Buffer.cpp
 *	file path:	C:\src\tactics-engine\libs\gd_dx11
 *	file base:	Buffer
 *	file ext:	cpp
 *	author:		Vitalii Trubchaninov
 *				venngraydog@gmail.com
 */

#include "gd_dx11/stdafx.h"
#include "gd_dx11/BufferImpl.h"

#include "gd_dx11/Device.h"
#include "gd_dx11/DeviceContext.h"

namespace tt{
namespace gd_dx11{

BufferImpl::BufferImpl()
: m_buffer()
{
}

BufferImpl::~BufferImpl()
{

}

//////////////////////////////////////////////////////////////////////////
Result BufferImpl::doCreate( Device* device, UInt dataType, UInt dataSize )
{
	D3D11_BUFFER_DESC bufferDesc;
	ZeroMemory(&bufferDesc, sizeof(bufferDesc));
	bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
	bufferDesc.ByteWidth = dataSize;
	bufferDesc.BindFlags = dataType;
	bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
	bufferDesc.MiscFlags = 0;
	bufferDesc.StructureByteStride = 0;

	HRESULT hr = device->d3dDevice()->CreateBuffer( &bufferDesc, NULL, m_buffer.getRef() );
	if( FAILED( hr ) )
		return Result::Failure();

	setSize(dataSize);

	return Result::Success();
}

utils::COMPointer<ID3D11Buffer>& BufferImpl::buffer()
{
	return m_buffer;
}

//////////////////////////////////////////////////////////////////////////
void BufferImpl::onLock( gd::DeviceContext* deviceContext )
{
	DeviceContext* dx11DeviceContext = getDx11Context(deviceContext);

	D3D11_MAPPED_SUBRESOURCE ms;
	ZeroMemory(&ms, sizeof(ms));
	HRESULT hr = dx11DeviceContext->d3dContext()->Map(buffer().get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
	if (SUCCEEDED(hr))
	{
		ttAssert(ms.pData != NULL);
		setData(ms.pData);
	}
}

void BufferImpl::onUnlock( gd::DeviceContext* deviceContext )
{
	setData(NULL);

	DeviceContext* dx11DeviceContext = getDx11Context(deviceContext);
	dx11DeviceContext->d3dContext()->Unmap(buffer().get(), 0);
}

} //namespace gd_dx11
} //namespace tt